package com.oa.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.joneying.common.annotation.CommonService;
import com.joneying.common.web.response.Resp;
import com.oa.admin.dto.UsingApplicationAddDTO;
import com.oa.admin.dto.UsingApplicationConditionDTO;
import com.oa.admin.dto.UsingApplicationFileAddDTO;
import com.oa.admin.entity.UsingApplicationFile;
import com.oa.admin.exportvo.UsingApplicationExportVO;
import com.oa.admin.mapper.UsingApplicationFileMapper;
import com.oa.admin.vo.UsingApplicationCheckVO;
import com.oa.admin.vo.UsingApplicationDetailsVO;
import com.oa.admin.vo.UsingApplicationFileDetailsVO;
import com.oa.admin.vo.UsingApplicationListVO;
import com.oa.core.PageResult;
import com.oa.admin.entity.UsingApplication;
import com.oa.admin.mapper.UsingApplicationMapper;
import com.oa.admin.service.IUsingApplicationService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.oa.core.constant.Constant;
import com.oa.core.enumm.CodeEnum;
import com.oa.core.enumm.ProcessDefineEnum;
import com.oa.core.exception.BusinessException;
import com.oa.core.exception.DataIsEmptyException;
import com.oa.core.utils.DateUtil;
import com.oa.core.utils.ExcelUtil;
import com.oa.system.dto.ApplyApprovalAddDTO;
import com.oa.system.entity.ApplyApproval;
import com.oa.system.entity.ApprovalNode;
import com.oa.system.entity.User;
import com.oa.system.service.IApplyApprovalService;
import com.oa.system.service.IApprovalNodeService;
import com.oa.system.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.plugins.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.oa.core.utils.Validate.validate;

/**
 * <p>
 * 用印申请表 服务实现类
 * </p>
 *
 * @author syb123
 * @since 2019-01-22
 */
@Service
public class UsingApplicationServiceImpl extends ServiceImpl<UsingApplicationMapper, UsingApplication> implements IUsingApplicationService {

    private final UsingApplicationMapper usingApplicationMapper;
    private final UsingApplicationFileMapper usingApplicationFileMapper;

    @Autowired
    private IApplyApprovalService applyApprovalService;

    @Autowired
    private IApprovalNodeService approvalNodeService;

    @Autowired
    private HttpServletResponse response;

    @Autowired
    public UsingApplicationServiceImpl(UsingApplicationMapper usingApplicationMapper, UsingApplicationFileMapper usingApplicationFileMapper) {
        this.usingApplicationMapper = usingApplicationMapper;
        this.usingApplicationFileMapper = usingApplicationFileMapper;
    }

    @Autowired
    private IUserService userService;

    @Override
    @CommonService
    public PageResult<UsingApplication> findList(Integer pageNum, Integer pageSize) {
        if (pageNum == null) {
            List<UsingApplication> list = usingApplicationMapper.findList();
            return new PageResult<>(list);
        } else {
            // 当前页，总条数 构造 page 对象
            Page<UsingApplication> page = new Page<>(pageNum, pageSize);
            //查询
            List<UsingApplication> list = usingApplicationMapper.findList(page);
            return new PageResult<>(list);
        }
    }

    /**
     * 根据id查询
     */
    @Override
    @CommonService
    public UsingApplication findUsingApplicationById(String id) {
        return usingApplicationMapper.findById(id);
    }

    /**
     * 用印申请
     *
     * @param usingApplicationAddDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional(rollbackFor = Exception.class)
    public Resp addUsingApplication(UsingApplicationAddDTO usingApplicationAddDTO) throws BusinessException, DataIsEmptyException {

        CheckoutUsingApplicationAddDTOParam(usingApplicationAddDTO);

        UsingApplication usingApplication = new UsingApplication();

        BeanUtils.copyProperties(usingApplicationAddDTO, usingApplication);
        usingApplication.setStatus("1");

        try {
            usingApplicationMapper.insert(usingApplication);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("添加用印申请失败!");
        }


        List<UsingApplicationFileAddDTO> usingApplicationFileAddDTOList = usingApplicationAddDTO.getUsingApplicationFileAddDTOList();
        if (CollUtil.isNotEmpty(usingApplicationFileAddDTOList)) {
            usingApplicationFileAddDTOList.forEach(x -> {
                UsingApplicationFile usingApplicationFile = new UsingApplicationFile();
                BeanUtils.copyProperties(x, usingApplicationFile);
                usingApplicationFile.setUsingId(usingApplication.getId());
                usingApplicationFileMapper.insert(usingApplicationFile);
            });
            User user = userService.selectById(usingApplication.getProposer());
            ApplyApprovalAddDTO applyApprovalAddDTO = new ApplyApprovalAddDTO();
            applyApprovalAddDTO.setApplyId(usingApplication.getId());
            applyApprovalAddDTO.setApprovalProcessId(ProcessDefineEnum.OFFICIAL_SEAL.getId());
            applyApprovalAddDTO.setApplyApprovalName(user.getName() + ProcessDefineEnum.OFFICIAL_SEAL.getText());
            applyApprovalAddDTO.setApprovalUserId(user.getId());

            return applyApprovalService.addApproval(applyApprovalAddDTO);
        }
        throw new BusinessException("添加用印申请附件失败!");
    }

    /**
     * 根据条件查询用印申请
     *
     * @param usingApplicationConditionDTO
     * @return
     */
    @Override
    @CommonService
    public PageResult<UsingApplicationListVO> findUsingApplicationListVoByCondition(UsingApplicationConditionDTO usingApplicationConditionDTO) throws BusinessException, DataIsEmptyException {
        CheckoutUsingApplicationConditionDTOParam(usingApplicationConditionDTO);

        Page page = usingApplicationConditionDTO.getPage();

        List<UsingApplicationListVO> list = usingApplicationMapper.findUsingApplicationListVOByCondition(page, usingApplicationConditionDTO);
//        if (CollUtil.isEmpty(list)) {
//            throw new DataIsEmptyException();
//        }
        return new PageResult<>(list, page.getPages());
    }

    /**
     * 根据主键id查询用印申请详情
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    public Resp findUsingApplicationDetailsById(String id) throws DataIsEmptyException {

        UsingApplicationDetailsVO usingApplicationDetailsVO = usingApplicationMapper.findUsingApplicationDetails(id);

        if (StringUtils.isEmpty(usingApplicationDetailsVO)) {
            throw new DataIsEmptyException();
        }

        List<UsingApplicationFileDetailsVO> usingApplicationFileDetailsVO = new ArrayList<>();

        List<UsingApplicationFile> usingApplicationFiles = usingApplicationFileMapper.selectList(new EntityWrapper<UsingApplicationFile>().
                eq("is_deleted", Constant.IS_DELETE_NO).eq("using_id", usingApplicationDetailsVO.getId()));

        if (CollUtil.isNotEmpty(usingApplicationFiles)) {
            usingApplicationFiles.forEach(x -> {
                UsingApplicationFileDetailsVO usingApplicationFileDetailsVO1 = new UsingApplicationFileDetailsVO();
                BeanUtils.copyProperties(x, usingApplicationFileDetailsVO1);
                usingApplicationFileDetailsVO.add(usingApplicationFileDetailsVO1);
            });
        }

        usingApplicationDetailsVO.setUsingApplicationFileDetailsVOList(usingApplicationFileDetailsVO);

        return new Resp<UsingApplicationDetailsVO>().success(usingApplicationDetailsVO);
    }

    /**
     * 导出用印申请列表
     *
     * @return
     */
    @Override
    @CommonService
    public Resp exportUsingApplicationList() throws BusinessException {

        List<UsingApplicationExportVO> usingApplicationExportVOList = usingApplicationMapper.findexportUsingApplicationList();

        String[] rowName = {"申请时间", "用印部门", "用印申请人", "用印文件名称", "文件份数", "发往单位", "文件类别", "加盖何种印章", "审批状态"};

        try {
            ExcelUtil.downloadExcel("用印申请表" + DateUtil.getDayMonth(), rowName, usingApplicationExportVOList, "用印申请表" + DateUtil.getDayMonth() + ".xls", response);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("导出用印申请excel表格失败!");
        }

        return new Resp<>().success("导出用印申请excel表格成功!");
    }

    /**
     * 参数校验
     *
     * @param
     */
    public void CheckoutUsingApplicationConditionDTOParam(UsingApplicationConditionDTO usingApplicationConditionDTO) throws BusinessException {
        if (!StringUtils.isEmpty(usingApplicationConditionDTO)) {
            List<String> validate = validate(usingApplicationConditionDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }
    }


    /**
     * 参数校验--用印申请
     *
     * @param
     */
    public void CheckoutUsingApplicationAddDTOParam(UsingApplicationAddDTO usingApplicationAddDTO) throws BusinessException {
        if (!StringUtils.isEmpty(usingApplicationAddDTO)) {
            List<String> validate = validate(usingApplicationAddDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }
    }


}
